﻿/*********************************************************************
 *
 *                             NOTICE
 *               COPYRIGHT (c) 2012 Panoscopix Software, Inc.
 *                UNPUBLISHED - ALL RIGHTS RESERVED
 * 
 *      This program is confidential, proprietary, and a trade
 *   secret of Panoscopix Software, Inc. The receipt or possession of
 *     this program does not convey any rights to reproduce or
 *      disclose its contents, or to manufacture, use, or sell
 *       anything that it may describe, in whole or in part, 
 *   without the specific written consent of Panoscopix Software, Inc.
 *
 * Implementation of the Prototype Factory Pattern (for Command).
 * 
 *******************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using FileSystem;
using FileSystem.Utility;

namespace FileSystem.Impl
{
	class CommandPrototypeFactory : ICommandFactory, ICommandPrototypeRegistry
	{
		private static CommandPrototypeFactory instance;
	
		private XMap<String, ICommandPrototype> prototypes;
	
		private CommandPrototypeFactory() {
			prototypes = new XMap<String, ICommandPrototype>();
		}
	
		public static CommandPrototypeFactory getInstance() {
			if (null == instance) {
				instance = new CommandPrototypeFactory();
			}
			return instance;
		}
	
		public ICollection<String> getNames() {
			return prototypes.getKeys();
		}

		public Boolean hasName(String name) {
			return prototypes.containsKey(name);
		}

		public ICommand create(String name) {
			ICommandPrototype p = prototypes.get(name);
			if (null == p) {
				throw new ArgumentException("Factory does not have class '" + name + "'.");
			}
			return p.clone();
		}

		public ICommand create(String name, String initializer) {
			ICommandPrototype p = prototypes.get(name);
			if (null == p) {
				throw new ArgumentException("Factory does not have class '" + name + "'.");
			}
			return p.clone(initializer);
		}
	
		public void register(String name, ICommandPrototype zombie) {
			if (String.IsNullOrEmpty(name) || prototypes.containsKey(name)) {
				throw new ArgumentException("Invalid name '" + name + "'.");
			}
			if (null == zombie) {
				throw new ArgumentException("Null prototype zombie.");
			}
			prototypes.put(name, zombie);
		}

        #region ICommandPrototypeRegistry Members


        public void describeCommand(ICommandHelpStrategy commandHelpStrategy)
        {
            foreach (string key in prototypes.getKeys())
            {
                commandHelpStrategy.Visit(prototypes.get(key));
            }
        }

        #endregion
    }
}
